﻿using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using ESSManageService.Common.Helper;
using ESSManageService.IServices;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.IdentityModel.Tokens;

namespace ESSManageService.Services
{
    /// <summary>
    /// 令牌与黑名单服务
    /// </summary>
    public class TokenBlacklistService : ITokenBlacklistService
    {
        private readonly IMemoryCache _cache;
        private readonly JwtSecurityTokenHandler _tokenHandler;

        public TokenBlacklistService(IMemoryCache cache)
        {
            _cache = cache;
            _tokenHandler = new JwtSecurityTokenHandler();
        }

        public async Task AddToBlacklistAsync(string token)
        {
            var jwtToken = _tokenHandler.ReadJwtToken(token);
            var expiryUtc = jwtToken.ValidTo;
            var expiryLocal = expiryUtc.ToLocalTime(); // 转换为本地时间
            var remaining = expiryLocal - DateTime.Now;

            if (remaining > TimeSpan.Zero)
            {
                var cacheKey = $"blacklist_{token}";
                _cache.Set(cacheKey, token, remaining);
            }
        }

        public async Task<bool> IsTokenBlacklistedAsync(string token)
        {
            var cacheKey = $"blacklist_{token}";
            return _cache.TryGetValue(cacheKey, out _);
        }

        /// <summary>
        /// 解析 JWT 令牌并获取用户信息
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public ClaimsPrincipal GetPrincipalFromToken(string token)
        {
            var tokenHandler = new JwtSecurityTokenHandler();

            if (token.IsNotEmptyOrNull() && tokenHandler.CanReadToken(token))
            {
                JwtSecurityToken jwtToken = tokenHandler.ReadJwtToken(token);

                long Uid = (jwtToken.Id).ObjToLong();
            }

            var validationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AppSettings.GetValue("Jwt:Key"))),
                ValidateIssuer = true,
                ValidIssuer = AppSettings.GetValue("Jwt:Issuer"),
                ValidateAudience = true,
                ValidAudience = AppSettings.GetValue("Jwt:Audience"),
                ValidateLifetime = false // 需要关闭有效期验证才能解析过期令牌
            };

            try
            {
                return tokenHandler.ValidateToken(token, validationParameters, out _);
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 颁发JWT字符串
        /// </summary>
        /// <param name="tokenModel"></param>
        /// <returns></returns>
        public JwtSecurityToken IssueJwt(Claim[] claims, out DateTime localExpiry)
        {
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AppSettings.GetValue("Jwt:Key")));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            // 设置过期时间，jwt使用的是UTC时间，所以这里要设置为 UtcNow(世界时)
            //var expiry = DateTime.UtcNow.AddMinutes(Convert.ToInt32(AppSettings.GetValue("Jwt:ExpiryInMinutes")));

            // 设置过期时间时添加时区说明
            var utcExpiry = DateTime.UtcNow.AddMinutes(Convert.ToInt32(AppSettings.GetValue("Jwt:ExpiryInMinutes")));
            localExpiry = DateTime.Now.AddMinutes(Convert.ToInt32(AppSettings.GetValue("Jwt:ExpiryInMinutes")));

            var token = new JwtSecurityToken(
                issuer: AppSettings.GetValue("Jwt:Issuer"),
                audience: AppSettings.GetValue("Jwt:Audience"),
                claims: claims,
                expires: utcExpiry,
                signingCredentials: creds
            );

            return token;
        }
    }
}
